package publishandsubscribe;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: LianBao
 * Date: 2025-03-19
 * Time: 20:57
 */
public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1. 建立连接(Connection)
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置连接参数:ip,端口号,用户名,密码,虚拟机
        connectionFactory.setHost("116.205.165.92");//ip
        connectionFactory.setPort(5672);//端口号,默认是5672
        connectionFactory.setUsername("Test");//用户名
        connectionFactory.setPassword("123");//密码
        connectionFactory.setVirtualHost("TestVirtualHost");//设置操作的虚拟机
        Connection connection = connectionFactory.newConnection();//从连接工厂中获取到连接

        //2. 开启通道(Channel)
        Channel channel = connection.createChannel();//通过connection开启通道

        //3. 声明交换机
        /**
         * 参数:
         * 1. exchange:交换机名称
         * 2. type:交换机类型
         *     DIRECT("direct"), 定向,直连,routing
         *     FANOUT("fanout"),扇形(⼴播), 每个队列都能收到消息
         * 	   TOPIC("topic"),通配符
         * 	   HEADERS("headers") 参数匹配(⼯作⽤的较少)
         * 3. durable: 是否持久化.
         * true-持久化,false⾮持久化.
         * 持久化可以将交换器存盘,在服务器重启的时候不会丢失相关信息
         * 4. autoDelete: ⾃动删除.
         * ⾃动删除的前提是⾄少有⼀个队列或者交换器与这个交换器绑定, 之后所有与这个交换器绑定的
         * 队列或者交换器都与此解绑.
         * ⽽不是这种理解: 当与此交换器连接的客⼾端都断开时,RabbitMQ会⾃动删除本交换器.
         * 5. internal: 内部使⽤, ⼀般falase.
         * 如果设置为true, 表⽰内部使⽤.
         * 客⼾端程序⽆法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种⽅式
         * 6. arguments: 参数
         */
        channel.exchangeDeclare("FANOUT_EXCHANGE", BuiltinExchangeType.FANOUT, false);

        //4.声明队列
        /**
         * queueDeclare方法的参数
         * queue:队列名
         * durable:可持久化
         * exclusive:是否独占(是否只能由一个消费者进行消费)
         * autoDelete:当没有人消费时,是否自动删除
         * arguments:参数
         */
        channel.queueDeclare("Queue1", true, false, false, null);
        channel.queueDeclare("Queue2", true, false, false, null);

        //5.交换机和队列进行绑定
        /**
         * 参数1:queue,队列名
         * 参数2:exchange,交换机名
         * 参数3:routingkey:路由key
         * 如果交换机类型为fanout,routingkey设置为""表示每个消费者都可以接受到全部信息
         */
        channel.queueBind("Queue1", "FANOUT_EXCHANGE", "");
        channel.queueBind("Queue2", "FANOUT_EXCHANGE", "");


        String msg = "HelloFANOUT";//消息的内容
        //发送消息
        /**
         * basicPublish方法的参数
         * exchange:交换机名称
         * routingKey:routingKey和队列名保持一致
         * props:属性配置
         * body:消息的内容
         */
        channel.basicPublish("FANOUT_EXCHANGE", "", null, msg.getBytes());

        System.out.println("消息发送成功");
        //6.释放资源
        channel.close();
        connection.close();

    }
}
